<?php

namespace common\observer;

use common\service\ModuleService;
use support\SingletonTrait;
use common\model\EntityModel;
use common\service\StepSkuService;
use common\service\StepWorkflowService;
use teamones\dbeventObserver\interfaces\SplSubject;
use teamones\dbeventObserver\interfaces\SplObserver;

/**
 * 监听实体的属性变化
 * 自动计算实体的工时
 */
class UpdateManhour implements SplObserver
{
    use SingletonTrait;

    /**
     * @param SplSubject $subject
     * @return void
     * @throws \Exception
     */
    function update(SplSubject $subject): void
    {
        $entity = $subject->getSubjectData();
        $entityId = $subject->getSplPrimaryId();
        $moduleCode = module_by_id($entity['module_id'])['code'];
        $moduleAttributeFields = ModuleService::getInstance()->getModuleAttributeFieldsWithAttributeIdMap($moduleCode);
        $moduleAttributeFields = array_keys($moduleAttributeFields);
        $updateKeys = array_keys($subject->getSplUpdateData());
        $changedAttributeFields = array_intersect($updateKeys, $moduleAttributeFields);
        // 属性没有发生变化 并且已经生成过工时
        if (empty($changedAttributeFields) && $entity['estimate_hours'] != 0 && $entity['cost_hours'] != 0) {
            return;
        }

        try {
            $moduleId = $entity['module_id'];
            $totalManHour = 0;
            $stepWorkflowId = $entity['step_workflow_id'];
            $stepCategoryDict = StepWorkflowService::getInstance()->getStepCategoryDictByStepWorkflowId([$stepWorkflowId]);

            if (!isset($stepCategoryDict[$stepWorkflowId])) {
                return;
            }
            foreach ($stepCategoryDict[$stepWorkflowId]['step_category_data'] as $stepCategoryItem) {
                list($tmpHour,) = StepSkuService::getInstance()->autoCalculationManHourByEntity($entityId, $moduleId, 'step_category', $stepCategoryItem['id'], $stepWorkflowId);
                $totalManHour += $tmpHour;
            }
            if ($entity['estimate_hours'] == $totalManHour) {
                return;
            }
            $updateData = [
                'id' => $entityId,
                'estimate_hours' => $totalManHour,
                'cost_hours' => $totalManHour,
            ];

            model(EntityModel::class)->modifyItem($updateData);
        } catch (\Throwable $e) {
            trace(format_exception_info($e), 'ERR');
        }
    }
}
